/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */
package com.yami.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.enums.PurchasesStatusEnum;
import com.yami.shop.bean.enums.StockBillStatus;
import com.yami.shop.bean.enums.StockBillType;
import com.yami.shop.bean.enums.StockType;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.vo.ExcelInfoVO;
import com.yami.shop.bean.vo.SupplierProdVO;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.Json;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.PoiExcelUtil;
import com.yami.shop.dao.PurchaseOrderMapper;
import com.yami.shop.service.*;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author YXF
 * @date 2021-09-08 10:42:01
 */
@Service
@AllArgsConstructor
public class PurchaseOrderServiceImpl extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> implements PurchaseOrderService {

    private final PurchaseOrderMapper purchaseOrderMapper;
    private final PurchaseProdService purchaseProdService;
    private final SupplierService supplierService;
    private final Snowflake snowflake;
    private final SupplierProdService supplierProdService;
    private final StockBillLogService stockBillLogService;

    @Override
    public IPage<PurchaseOrder> pagePurchaseOrder(PageParam<PurchaseOrder> page, PurchaseOrder purchaseOrder) {
        return purchaseOrderMapper.pagePurchaseOrder(page, purchaseOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePurchaseOrder(PurchaseOrder purchaseOrder) {
        Supplier supplier = supplierService.getOne(new LambdaQueryWrapper<Supplier>()
                .eq(Supplier::getSupplierId, purchaseOrder.getSupplierId())
                .eq(Supplier::getShopId, purchaseOrder.getShopId())
                .eq(Supplier::getStatus, 1));

        if (Objects.isNull(supplier)) {
            throw new YamiShopBindException("yami.supplier.not.exist.or.disabled");
        }
        Map<Long, SupplierProd> supplierProdMap = null;
        if (Objects.equals(supplier.getIsDefault(), 0)) {
            List<SupplierProd> supplierProds = supplierProdService.list(new LambdaQueryWrapper<SupplierProd>().eq(SupplierProd::getSupplierId, purchaseOrder.getSupplierId()));
            Map<Long, SupplierProd> map = supplierProds.stream().collect(Collectors.toMap(SupplierProd::getSupplierProdId, s -> s));
            long count = purchaseOrder.getPurchaseProds().stream().filter(purchaseProd -> Objects.isNull(map.get(purchaseProd.getSupplierProdId()))).count();
            if (count > 0) {
                throw new YamiShopBindException("yami.purchased.prod.not.exist.or.disabled");
            }
            supplierProdMap = map;
        }
        double totalAmount = 0D;
        int totalStock = 0;
        String purchaseNumber = Constant.PURCHASES_ORDER + snowflake.nextId();
        for (PurchaseProd purchaseProd : purchaseOrder.getPurchaseProds()) {
            totalAmount = Arith.add(totalAmount, purchaseProd.getPurchaseAmount());
            totalStock += purchaseProd.getPurchaseStock();
            purchaseProd.setStatus(PurchasesStatusEnum.WAIT_STOCK.value());
            purchaseProd.setActualStock(0);
            if (Objects.equals(supplier.getIsDefault(), 0)) {
                if (!supplierProdMap.containsKey(purchaseProd.getSupplierProdId())) {
                    throw new YamiShopBindException("yami.purchased.prod.not.exist.or.disabled");
                }
                SupplierProd supplierProd = supplierProdMap.get(purchaseProd.getSupplierProdId());
                purchaseProd.setProdId(supplierProd.getProdId());
                purchaseProd.setSkuId(supplierProd.getSkuId());
            }
            purchaseProd.setPurchaseNumber(purchaseNumber);
        }
        Date date = new Date();
        purchaseOrder.setCreateTime(date);
        purchaseOrder.setUpdateTime(date);
        purchaseOrder.setTotalAmount(totalAmount);
        purchaseOrder.setTotalStock(totalStock);
        purchaseOrder.setActualTotalStock(0);
        purchaseOrder.setStatus(PurchasesStatusEnum.WAIT_STOCK.value());
        purchaseOrder.setPurchaseNumber(purchaseNumber);
        this.save(purchaseOrder);
        purchaseProdService.saveBatch(purchaseOrder.getPurchaseProds());
    }

    @Override
    public PurchaseOrder info(Long purchaseOrderId) {
        PurchaseOrder purchaseOrder = purchaseOrderMapper.info(purchaseOrderId);
        if (Objects.isNull(purchaseOrder)) {
            throw new YamiShopBindException("yami.purchased.order.not.exist");
        }
        if (CollUtil.isNotEmpty(purchaseOrder.getPurchaseProds())) {
            purchaseProdService.loadProdAndSkuInfo(purchaseOrder.getPurchaseProds());
        }
        return purchaseOrder;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void inbound(PurchaseOrder purchaseOrder) {
        PurchaseOrder purchaseOrderDb = purchaseOrderMapper.selectById(purchaseOrder.getPurchaseOrderId());
        if (!Objects.equals(purchaseOrder.getShopId(), purchaseOrderDb.getShopId())) {
            throw new YamiShopBindException("yami.no.auth");
        }
        if (Objects.equals(purchaseOrderDb.getStatus(), PurchasesStatusEnum.VOIDED.value())) {
            throw new YamiShopBindException("yami.purchases.order.voided");
        }
        if (Objects.equals(purchaseOrderDb.getStatus(), PurchasesStatusEnum.COMPLETION.value())) {
            throw new YamiShopBindException("yami.purchases.order.complete");
        }
        purchaseOrderDb.setDeliverTime(purchaseOrder.getDeliverTime());
        List<PurchaseProd> list = purchaseProdService.list(new LambdaQueryWrapper<PurchaseProd>().eq(PurchaseProd::getPurchaseNumber, purchaseOrderDb.getPurchaseNumber()));
        Map<Long, PurchaseProd> map = purchaseOrder.getPurchaseProds().stream().collect(Collectors.toMap(PurchaseProd::getPurchaseProdId, p -> p));
        purchaseOrderDb.setRemark(purchaseOrder.getRemark());
        Iterator<PurchaseProd> iterator = list.iterator();
        Integer actualTotalStock = 0;
        List<StockBillLogItem> stockBillLogItems = new ArrayList<>();
        boolean complete = true;
        while (iterator.hasNext()) {
            PurchaseProd purchaseProdDb = iterator.next();
            if (!map.containsKey(purchaseProdDb.getPurchaseProdId()) || Objects.equals(purchaseProdDb.getStatus(), 0)) {
                actualTotalStock += purchaseProdDb.getActualStock();
                iterator.remove();
                if (purchaseProdDb.getActualStock() < purchaseProdDb.getPurchaseStock() && !Objects.equals(purchaseProdDb.getStatus(), 0)) {
                    complete = false;
                }
                continue;
            }
            PurchaseProd purchaseProd = map.get(purchaseProdDb.getPurchaseProdId());
            if (!Objects.equals(purchaseProdDb.getStatus(), 1) && !Objects.equals(purchaseProdDb.getStatus(), 2)) {
                continue;
            }
            Integer actualStock = purchaseProdDb.getActualStock() + purchaseProd.getActualStock();
            if (actualStock > 0 && purchaseProdDb.getPurchaseStock() > actualStock) {
                purchaseProdDb.setStatus(2);
            }
            if (Objects.equals(purchaseProdDb.getPurchaseStock(), actualStock)) {
                purchaseProdDb.setStatus(3);
            }
            Integer changeStock = actualStock - purchaseProdDb.getActualStock();
            if (complete && actualStock < purchaseProd.getPurchaseStock()) {
                complete = false;
            }
            if (actualStock - purchaseProdDb.getActualStock() <= 0) {
                continue;
            }
            stockBillLogItems.add(loadStockBillLogItem(purchaseProd, changeStock));
            purchaseProdDb.setActualStock(actualStock);
            actualTotalStock += purchaseProdDb.getActualStock();
        }
        // 部分入库
        if (actualTotalStock > 0 && Objects.equals(purchaseOrderDb.getStatus(), 1)) {
            purchaseOrderDb.setStatus(2);
        }
        // 已完成
        if (complete) {
            purchaseOrderDb.setStatus(3);
        }
        if (CollUtil.isNotEmpty(stockBillLogItems)) {
            StockBillLog stockBillLog = loadStockBillLog(purchaseOrderDb, stockBillLogItems);
            stockBillLogService.saveInfo(stockBillLog);
        }
        updateById(purchaseOrderDb);
        purchaseProdService.updateBatchById(list);
    }

    private StockBillLog loadStockBillLog(PurchaseOrder purchaseOrderDb, List<StockBillLogItem> stockBillLogItems) {
        StockBillLog stockBillLog = new StockBillLog();
        stockBillLog.setSourceOrderNo(purchaseOrderDb.getPurchaseNumber());
        stockBillLog.setStockBillType(StockBillType.PURCHASE_STORAGE.value());
        stockBillLog.setEmployeeId(purchaseOrderDb.getEmployeeId());
        stockBillLog.setBusinessTime(purchaseOrderDb.getDeliverTime());
        stockBillLog.setShopId(purchaseOrderDb.getShopId());
        stockBillLog.setRemark(purchaseOrderDb.getRemark());
        stockBillLog.setSupplierId(purchaseOrderDb.getSupplierId());
        stockBillLog.setType(StockType.WAREHOUSING.value());
        stockBillLog.setStatus(StockBillStatus.SUCCESS.value());
        double totalAmount = 0.0;
        int totalCount = 0;
        for (StockBillLogItem stockBillLogItem : stockBillLogItems) {
            totalAmount = Arith.add(totalAmount, Arith.mul(stockBillLogItem.getUnitPrice(), stockBillLogItem.getStockCount()));
            totalCount += stockBillLogItem.getStockCount();
        }
        stockBillLog.setTotalAmount(totalAmount);
        stockBillLog.setTotalCount(totalCount);
        stockBillLog.setStockBillLogItems(stockBillLogItems);
        return stockBillLog;
    }

    private StockBillLogItem loadStockBillLogItem(PurchaseProd purchaseProd, Integer stock) {
        StockBillLogItem stockBillLogItem = new StockBillLogItem();
        stockBillLogItem.setStockCount(stock);
        stockBillLogItem.setUnitPrice(purchaseProd.getPurchasePrice());
        stockBillLogItem.setProdId(purchaseProd.getProdId());
        stockBillLogItem.setSkuId(purchaseProd.getSkuId());
        return stockBillLogItem;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void nullify(Long shopId, Long purchaseOrderId) {
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectById(purchaseOrderId);
        if (!Objects.equals(purchaseOrder.getShopId(), shopId)) {
            throw new YamiShopBindException("yami.no.auth");
        }
        if (!Objects.equals(purchaseOrder.getStatus(), 1)) {
            throw new YamiShopBindException("yami.prod.common.invalid");
        }
        purchaseOrder.setStatus(0);
        purchaseOrderMapper.updateById(purchaseOrder);
        List<PurchaseProd> list = purchaseProdService.list(new LambdaQueryWrapper<PurchaseProd>().eq(PurchaseProd::getPurchaseNumber, purchaseOrder.getPurchaseNumber()));
        for (PurchaseProd purchaseProd : list) {
            purchaseProd.setStatus(0);
        }
        purchaseProdService.updateBatchById(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void complete(Long shopId, Long purchaseOrderId) {
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectById(purchaseOrderId);
        if (!Objects.equals(purchaseOrder.getShopId(), shopId)) {
            throw new YamiShopBindException("yami.no.auth");
        }
        if (!Objects.equals(purchaseOrder.getStatus(), PurchasesStatusEnum.PARTIALLY_STOCK.value())) {
            throw new YamiShopBindException("yami.prod.common.invalid");
        }
        purchaseOrder.setStatus(3);
        purchaseOrderMapper.updateById(purchaseOrder);
        List<PurchaseProd> list = purchaseProdService.list(new LambdaQueryWrapper<PurchaseProd>().eq(PurchaseProd::getPurchaseNumber, purchaseOrder.getPurchaseNumber()));
        for (PurchaseProd purchaseProd : list) {
            purchaseProd.setStatus(3);
        }
        purchaseProdService.updateBatchById(list);
    }

    @Override
    public void downloadModel(HttpServletResponse response) {
        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getBigWriter();
        // 商品导出or模板
        String[] headerCn = {"*商品编码(必填)", "商品名称", "采购数量", "采购价格"};
        String[] headerEn = {"*Product code(Required)", "Product name", "Purchase Num", "Purchase Price"};
        List<String> headerList = Arrays.asList(Objects.equals(I18nMessage.getDbLang(), 0) ? headerCn : headerEn);
        Sheet sheet = writer.getSheet();
        sheet.setColumnWidth(0, 50 * 256);
        sheet.setColumnWidth(1, 60 * 256);
        sheet.setColumnWidth(2, 30 * 256);
        sheet.setColumnWidth(3, 30 * 256);

        writer.merge(headerList.size() - 1, "采购信息整理");
        writer.writeRow(headerList);

        PoiExcelUtil.writeExcel(response, writer);
    }

    @Override
    public ExcelInfoVO parseFile(MultipartFile file, Long shopId, Long supplierId) {
        ExcelInfoVO excelInfoVO = new ExcelInfoVO();
        Supplier supplier = supplierService.getById(supplierId);
        if(!Objects.equals(shopId, supplier.getShopId())) {
            // 没有权限进行操作
            throw new YamiShopBindException("yami.no.auth");
        }
        List<String> errorList = new ArrayList<>();
        List<String> partyCodeList = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream();
             Workbook workBook = WorkbookFactory.create(inputStream)) {
            //读取工作表
            Sheet sheet = workBook.getSheetAt(0);
            int rowNumber = sheet.getPhysicalNumberOfRows();

            //校验是否填写内容
            if (rowNumber <= Constant.EXCEL_BEGIN_ROW) {
                // 文件无内容
                throw new YamiShopBindException("yami.document.no.content");
            }
            // * 2.1不是Excel文件，直接返回提示信息
            if (!(file.getOriginalFilename().contains(Constant.XLS_FILE) || file.getOriginalFilename().contains(Constant.XLSX_FILE))) {
                // 格式错误
                throw new YamiShopBindException("yami.file.error");
            }

            List<PurchaseProd> products = new ArrayList<>();
            List<String> partyCodes = new ArrayList<>();
            //循环读取每一行数据并校验
            for (int i = 2; i < rowNumber; i++) {
                try {
                    //读取行
                    Row row = sheet.getRow(i);
                    int cell = 0;
                    String partyCode = PoiExcelUtil.getRowValue(row, cell, false);
                    cell++;
                    String purchaseStock = PoiExcelUtil.getRowValue(row, ++cell, true);
                    String purchasePrice = PoiExcelUtil.getRowValue(row, ++cell, true);
                    if (StrUtil.isBlank(partyCode)) {
                        throw new YamiShopBindException("yami.purchases.order.party.code");
                    }
                    partyCodeList.add(partyCode);
                    PurchaseProd purchaseProd = new PurchaseProd();
                    purchaseProd.setPartyCode(partyCode);
                    purchaseProd.setPurchaseStock(Integer.valueOf(purchaseStock));
                    purchaseProd.setPurchasePrice(Double.valueOf(purchasePrice));
                    products.add(purchaseProd);
                    partyCodes.add(partyCode);
                } catch (Exception e) {
                    //错误信息提示
                    errorList.add("第" + (i + 1) + "行数据有错误：" + e.getMessage());
                }
            }
            //处理合并数据
            if (CollectionUtils.isNotEmpty(partyCodes)) {
                loadSupplierProdVO(supplierId, excelInfoVO, supplier, errorList, partyCodeList, products);
            }
        } catch (Exception e) {
            errorList.add(e.getMessage());
        }
        if (CollUtil.isNotEmpty(errorList)) {
            excelInfoVO.setErrorMsg(errorList.toString());
        }
        return excelInfoVO;
    }

    private void loadSupplierProdVO(Long supplierId, ExcelInfoVO excelInfoVO, Supplier supplier, List<String> errorList, List<String> partyCodeList, List<PurchaseProd> products) {
        List<String> errorCodeList = new ArrayList<>();
        List<SupplierProdVO> supplierProdList;
        if (Objects.equals(supplier.getIsDefault(), 1)) {
            supplierProdList = supplierProdService.listSupplierProdByPartyCodeList(partyCodeList);
        } else {
            supplierProdList = supplierProdService.listSupplierProd(supplierId);
        }
        Map<String, SupplierProdVO> map = supplierProdList.stream().collect(Collectors.toMap(SupplierProdVO::getPartyCode, p -> p));
        Iterator<PurchaseProd> iterator = products.iterator();
        while(iterator.hasNext()) {
            PurchaseProd product = iterator.next();
            // 不是默认供应商需要判断供应商下是否包含了该商品
            if (Objects.equals(supplier.getIsDefault(), 0) && !map.containsKey(product.getPartyCode())) {
                errorCodeList.add(product.getPartyCode());
                iterator.remove();
                continue;
            } else if (!map.containsKey(product.getPartyCode())) {
                continue;
            }
            SupplierProdVO supplierProdVO = map.get(product.getPartyCode());
            product.setProdId(supplierProdVO.getProdId());
            product.setProdName(supplierProdVO.getProdName());
            product.setPic(supplierProdVO.getPic());
            product.setSkuName(supplierProdVO.getSkuName());
            product.setStocks(supplierProdVO.getStocks());
            product.setSkuId(supplierProdVO.getSkuId());
            if (Objects.equals(supplier.getIsDefault(), 1)) {
                product.setMinOrderQuantity(1);
                product.setSupplierProdId(0L);
                product.setPurchasePrice(supplierProdVO.getPurchasePrice());
                product.setSkuId(supplierProdVO.getSkuId());
            } else {
                product.setMinOrderQuantity(supplierProdVO.getMinOrderQuantity());
                product.setSupplierProdId(supplierProdVO.getSupplierProdId());
                if (product.getPurchasePrice() < supplierProdVO.getPurchasePrice()){
                    product.setPurchasePrice(supplierProdVO.getPurchasePrice());
                }
                if (product.getPurchaseStock() <  supplierProdVO.getMinOrderQuantity()){
                    product.setPurchaseStock(supplierProdVO.getMinOrderQuantity());
                }
            }
        }
        if (CollUtil.isNotEmpty(errorCodeList)) {
            errorList.add(I18nMessage.getMessage("yami.purchases.order.error.code") + Constant.COLON + errorCodeList.toString());
        }
        if (CollUtil.isNotEmpty(products)) {
            excelInfoVO.setData(Json.toJsonString(products));
        }
    }

    @Override
    public void export(PurchaseOrder purchaseOrder, HttpServletResponse response) {
        PurchaseOrder info = this.info(purchaseOrder.getPurchaseOrderId());
        createExcel(info.getPurchaseProds(), response);
    }

    @Override
    public void inboundDownloadModel(HttpServletResponse response) {
        createExcel(null, response);
    }

    @Override
    public ExcelInfoVO inboundParseFile(MultipartFile file, Long shopId, Long purchaseOrderId) {
        ExcelInfoVO excelInfoVO = new ExcelInfoVO();
        PurchaseOrder purchaseOrder = this.info(purchaseOrderId);
        if(!Objects.equals(shopId, purchaseOrder.getShopId())) {
            // 没有权限进行操作
            throw new YamiShopBindException("yami.no.auth");
        }
        List<String> errorList = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream();
             Workbook workBook = WorkbookFactory.create(inputStream)) {
            //读取工作表
            Sheet sheet = workBook.getSheetAt(0);
            int rowNumber = sheet.getPhysicalNumberOfRows();

            //校验是否填写内容
            if (rowNumber <= Constant.EXCEL_BEGIN_ROW) {
                // 文件无内容
                throw new YamiShopBindException("yami.document.no.content");
            }
            // * 2.1不是Excel文件，直接返回提示信息
            if (!(file.getOriginalFilename().contains(Constant.XLS_FILE) || file.getOriginalFilename().contains(Constant.XLSX_FILE))) {
                // 格式错误
                throw new YamiShopBindException("yami.file.error");
            }
            Map<String, PurchaseProd> purchaseProdMap = purchaseOrder.getPurchaseProds().stream()
                    .filter(purchaseProd -> !Objects.equals(purchaseOrder.getStatus(), 0))
                    .collect(Collectors.toMap(PurchaseProd::getPartyCode, p -> p));
            List<PurchaseProd> products = new ArrayList<>();
            List<String> errorCodeList = new ArrayList<>();
            //循环读取每一行数据并校验
            for (int i = 2; i < rowNumber; i++) {
                try {
                    //读取行
                    Row row = sheet.getRow(i);
                    int cell = 0;
                    String partyCode = PoiExcelUtil.getRowValue(row, cell, false);
                    cell += 3;
                    String actualStock = PoiExcelUtil.getRowValue(row, ++cell, true);
                    if (StrUtil.isBlank(partyCode)) {
                        throw new YamiShopBindException("yami.purchases.order.party.code");
                    }
                    if (!purchaseProdMap.containsKey(partyCode)) {
                        errorCodeList.add(partyCode);
                        continue;
                    }
                    PurchaseProd purchaseProdDb = purchaseProdMap.get(partyCode);
                    PurchaseProd purchaseProd = new PurchaseProd();
                    purchaseProd.setPurchaseProdId(purchaseProdDb.getPurchaseProdId());
                    purchaseProd.setPartyCode(partyCode);
                    purchaseProd.setPurchasePrice(purchaseProdDb.getPurchasePrice());
                    purchaseProd.setPurchaseStock(purchaseProdDb.getPurchaseStock());
                    Integer emainingStock = purchaseProdDb.getPurchaseStock() - purchaseProdDb.getActualStock();
                    purchaseProd.setRemainingStock(emainingStock < 0 ? 0 : emainingStock);
                    purchaseProd.setActualStock(Integer.valueOf(actualStock));
                    if (purchaseProd.getActualStock() < 0) {
                        purchaseProd.setActualStock(0);
                    }
                    purchaseProd.setProdId(purchaseProdDb.getProdId());
                    purchaseProd.setProdName(purchaseProdDb.getProdName());
                    purchaseProd.setPic(purchaseProdDb.getPic());
                    purchaseProd.setSkuId(purchaseProdDb.getSkuId());
                    purchaseProd.setSkuName(purchaseProdDb.getSkuName());
                    products.add(purchaseProd);
                } catch (Exception e) {
                    //错误信息提示
                    errorList.add("第" + (i + 1) + "行数据有错误：" + e.getMessage());
                }
            }
            excelInfoVO.setData(Json.toJsonString(products));
        } catch (Exception e) {
            errorList.add(e.getMessage());
        }
        if (CollUtil.isNotEmpty(errorList)) {
            excelInfoVO.setErrorMsg(errorList.toString());
        }
        return excelInfoVO;
    }

    private void createExcel(List<PurchaseProd> list, HttpServletResponse response) {
        ExcelWriter writer = ExcelUtil.getBigWriter();
        List<String> headerList;
        String[] headerCn;
        String[] headerEn;
        headerCn = new String[]{"商品编号", "商品名称", "预计入库量", "剩余入库量", "实际入库量"};
        headerEn = new String[]{"Product Code", "Product Name", "Tel", "Contact Name", "Contact Tel"};
        headerList = Arrays.asList(Objects.equals(I18nMessage.getDbLang(), 0) ? headerCn : headerEn);
        Sheet sheet = writer.getSheet();
        sheet.setColumnWidth(0, 40 * 256);
        for (int i = 1; i < 9; i++) {
            sheet.setColumnWidth(i, 20 * 256);
        }
        sheet.setColumnWidth(9, 50 * 256);
        writer.merge(headerList.size() - 1, Objects.equals(I18nMessage.getDbLang(), 0) ? "采购入库信息" : "Purchase inbound");
        writer.writeRow(headerList);
        int row = 1;
        if (CollectionUtil.isNotEmpty(list)) {
            for (PurchaseProd purchaseProd : list) {
                int stock = purchaseProd.getPurchaseStock() - purchaseProd.getActualStock();
                int firstRow = ++row;
                int col = -1;
                //商品编号
                PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, purchaseProd.getPartyCode());
                //商品名称
                String prodName = purchaseProd.getProdName() + " " + purchaseProd.getSkuName();
                PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, prodName);
                //预计入库量
                PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, purchaseProd.getPurchaseStock());
                //剩余入库量
                PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, stock);
                //实际入库量
                PoiExcelUtil.mergeIfNeed(writer, firstRow, firstRow, ++col, col, stock);
            }
        }
        PoiExcelUtil.writeExcel(response, writer);
    }
}
